package com.douqu.game.main.msg;

import com.douqu.game.core.config.StableDataConfig;
import com.douqu.game.core.config.common.GoodsData;
import com.douqu.game.core.config.major.MajorConfig;
import com.douqu.game.core.config.major.MajorMergeConfig;
import com.douqu.game.core.controller.PlayerController;
import com.douqu.game.core.database.model.PlayerModel;
import com.douqu.game.core.e.E_BattleDetailType;
import com.douqu.game.core.e.E_StableDataType;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.battle.BattleInitParam;
import com.douqu.game.core.entity.common.TwoTuple;
import com.douqu.game.core.entity.db.CardDB;
import com.douqu.game.core.entity.db.PropDB;
import com.douqu.game.core.entity.ext.BagInfo;
import com.douqu.game.core.entity.ext.SettingInfo;
import com.douqu.game.core.entity.ext.TaskInfo;
import com.douqu.game.core.entity.ext.data.major.CollectData;
import com.douqu.game.core.entity.ext.data.major.RefiningData;
import com.douqu.game.core.entity.ext.data.major.TalentData;
import com.douqu.game.core.entity.world.WorldCollectBean;
import com.douqu.game.core.entity.world.WorldCollectData;
import com.douqu.game.core.factory.*;
import com.douqu.game.core.i.ICalculateRandomField;
import com.douqu.game.core.protobuf.SGChallengeProto;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.protobuf.SGMainProto;
import com.douqu.game.core.protobuf.SGMajorProto.*;
import com.douqu.game.core.util.CoreUtils;
import com.douqu.game.core.util.LogUtils;
import com.douqu.game.core.util.StringUtils;
import com.douqu.game.core.web.request.MajorBattleParam;
import com.douqu.game.main.GameServer;
import com.douqu.game.main.msg.param.RequestParam;
import com.douqu.game.main.service.PlayerService;
import com.douqu.game.main.util.MsgUtils;
import com.google.protobuf.InvalidProtocolBufferException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @author: zhenfei
 * 2018-03-14
 */
@Component
public class MajorMsgChannel implements AMsgChannel {


    @Autowired
    private PlayerService playerService;


    @Override
    public void messageChannel(int code, PlayerController playerController, byte[] data) throws Exception {
        if (playerController == null)
            throw new Exception("playerController is null");

        switch (code) {
            case SGMainProto.E_MSG_ID.MsgID_Major_Battle_VALUE:
                majorBattle(playerController, code, data);
                break;
            /*************************采集*****************************/
            case SGMainProto.E_MSG_ID.MsgID_Major_CollectInit_VALUE:
                collectInit(playerController, code, data);
                break;
            case SGMainProto.E_MSG_ID.MsgID_Major_CollectRevengeList_VALUE:
                collectRevengeList(playerController, code, data);
                break;
            case SGMainProto.E_MSG_ID.MsgID_Major_CollectStart_VALUE:
                collectStart(playerController, code, data);
                break;
            case SGMainProto.E_MSG_ID.MsgID_Major_CollectProductionReceiver_VALUE:
                collectProductionReceiver(playerController, code, data);
                break;
            /*************************合成*****************************/
            case SGMainProto.E_MSG_ID.MsgID_Major_MergeInit_VALUE:
                mergeInit(playerController, code, data);
                break;
            case SGMainProto.E_MSG_ID.MsgID_Major_Merge_VALUE:
                merge(playerController, code, data);
                break;
            /*******************吃草和药水加经验************/
            case SGMainProto.E_MSG_ID.MsgID_Major_Eat_VALUE:
                eatMajorGoods(playerController, code, data);
                break;
            /*************************吃药*****************************/
            case SGMainProto.E_MSG_ID.MsgID_Major_UseLiquid_VALUE:
                userLiquid(playerController, code, data);
                break;
            /*************************天赋****************************/
            case SGMainProto.E_MSG_ID.MsgID_Talent_Init_VALUE:
                initTalent(playerController, code, data);
                break;
            case SGMainProto.E_MSG_ID.MsgID_Talent_Operation_VALUE:
                operationTalent(playerController, code, data);
                break;
            case SGMainProto.E_MSG_ID.MsgID_Talent_Clear_VALUE:
                clearTalent(playerController, code, data);
                break;
            default:
                break;
        }
    }

    /**
     * 吃草药和药水添加经验
     * @param playerController
     * @param code
     * @param data
     */
    private void eatMajorGoods(PlayerController playerController, int code, byte[] data) {
        C2S_MajorEat request = null;
        try {
            request = C2S_MajorEat.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        if (request == null) {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        int type = request.getType();
        int quality = request.getQuality();
        LogUtils.info("1723--收到的参数 type:"+type+" quality:"+quality);
        BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
        //吃药草
        List<PropDB> list=  bagInfo.getTypePropList(type);
        if (list.isEmpty()){
            playerController.sendWarn(WordFactory.EXPERIENCE_PROPS_IS_NULL);
            return;
        }
        if ( !playerController.getPlayer().getCollectData().addExpByType(type,quality)){
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        S2C_MajorEat.Builder response = S2C_MajorEat.newBuilder();
        Player player = playerController.getPlayer();
        if (player == null){
            return;
        }
        if (type == ConstantFactory.PROP_TYPE_GRASS) {
            //更新采集等级
            player.getCollectData().calculateLevel();
            response.setMajorType(SGCommonProto.E_MAJOR_TYPE.MAJOR_TYPE_COLLECT);
            response.setLevel(player.getMajorInfo().getRefiningData().getLevel());
            playerController.sendMsg(code, response.build().toByteArray());
        }else if (type == ConstantFactory.PROP_TYPE_LIQUID){
            //更新炼药等级
            player.getMajorInfo().getRefiningData().calculateLevel();
            response.setMajorType(SGCommonProto.E_MAJOR_TYPE.MAJOR_TYPE_REFINING);
            response.setLevel(player.getMajorInfo().getRefiningData().getLevel());
            playerController.sendMsg(code, response.build().toByteArray());
        }else {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
        }

    }

    /**
     * 重置天赋
     * @param playerController
     * @param code
     * @param data
     */
    private void clearTalent(PlayerController playerController, int code, byte[] data) {
        C2S_TalentClear request = null;
        try {
            request = C2S_TalentClear.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        if (request == null) {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        SGCommonProto.E_TALENT_TYPE type = request.getType();
        BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
        TalentData talentData =playerController.getPlayer().getTalentData();
        playerController.getPlayer().getTalentData().getTalentLibraryMap();
        if (talentData.getTalentLibraryMap().get(type.getNumber())==null){
            LogUtils.debug("no talent data!!!");
            playerController.sendWarn(WordFactory.TALENT_CLEAR_RESET);
        }
        // 消耗钻石  多少级免费不用消耗钻石
        StableDataConfig dataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.TALENT_CLEAR_LEVEL.getCode());
        if ( playerController.getPlayer().getLv() >dataConfig.intValue){
            switch (type){
                case TALENT_TYPE_ATK:
                    dataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.TALENT_ATK_CLEAR.getCode());
                    break;
                case TALENT_TYPE_DEF:
                    dataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.TALENT_DEF_CLEAR.getCode());
                    break;
                case TALENT_TYPE_STRATEGY:
                    dataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.TALENT_SLG_CLEAR.getCode());
                    break;
            }

            int goodsCount = bagInfo.getGoodsCount(dataConfig.goods[0].type, dataConfig.goods[0].id);
            if (goodsCount < dataConfig.goods[0].value) {
                LogUtils.debug("资源不够 自己拥有:" + goodsCount + "     ,需要：" + dataConfig.goods[0].value);
                playerController.sendWarn(WordFactory.RESET_ERROR);
            }
        }

        S2C_TalentClear.Builder response = S2C_TalentClear.newBuilder();
        talentData.clearTalent(type);
        response.setType(request.getType());
        response.setTalentPoint( talentData.getTalentNote());
        playerController.sendMsg(code, response.build().toByteArray());
        playerController.updateFC();
    }

    /**
     * 操作天赋
     * @param playerController
     * @param code
     * @param data
     */
    private void operationTalent(PlayerController playerController, int code, byte[] data) {
        C2S_TalentOperation request = null;
        try {
            request = C2S_TalentOperation.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        if (request == null) {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        SGCommonProto.E_TALENT_OPERATION handleType= request.getOperation();
        int talentId =request.getTalentId();
        boolean isOnceOperation = request.getIsOnceOperation();
        LogUtils.info("操作天赋收到的参数:"+handleType+"--"+talentId+"--"+isOnceOperation);
        S2C_TalentOperation.Builder response = S2C_TalentOperation.newBuilder();
        SGCommonProto.TalentObject.Builder builder= playerController.getPlayer().getTalentData().onceUpdateTalent(handleType,talentId,isOnceOperation);
        if (builder == null){
            playerController.sendWarn(WordFactory.ESCALATION_ERROR);
            return;
        }
        response.setTalent(builder);
        response.setTalentPoint(playerController.getPlayer().getTalentData().getTalentNote());
        playerController.sendMsg(code, response.build().toByteArray());
        playerController.updateFC();
    }

    /**
     * 初始化天赋
     * @param playerController
     * @param code
     * @param data
     */
    private void initTalent(PlayerController playerController, int code, byte[] data) {
        C2S_TalentInit request = null;
        try {
            request = C2S_TalentInit.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        if (request == null) {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        //是否拉取天赋列表
        boolean isList = request.getInitList();
        S2C_TalentInit.Builder response = S2C_TalentInit.newBuilder();
        if (isList){
//            for (SGCommonProto.TalentObject.Builder talent:playerController.getPlayer().getTalentData().getAllTalent()){
//                response.addTalent(talent);
//            }
            playerController.getPlayer().getTalentData().getAllTalent().forEach(response::addTalent);
        }
        response.setInitList(isList);
        response.setLv(playerController.getPlayer().getTalentData().getTalentLv());
        response.setExp(playerController.getPlayer().getTalentData().getTalentExp());
        response.setTalentPoint(playerController.getPlayer().getTalentData().getTalentNote());
        playerController.sendMsg(code, response.build().toByteArray());
    }


    /**
     * 使用药水
     *
     * @param playerController
     * @param code
     * @param data
     */
    private void userLiquid(PlayerController playerController, int code, byte[] data) {
        C2S_MajorUseLiquid request = null;
        try {
            request = C2S_MajorUseLiquid.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        if (request == null) {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        LogUtils.debug("使用药水请求参数:" + request.toString());

        int propId = request.getPropId();
        SGCommonProto.E_GAME_ROLE_TYPE roleType = request.getRoleType();
        int useCount = request.getUseCount();
        int cardId = request.getCardId();

        BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);

        PropDB propDB = bagInfo.getPropById(propId);
        if (propDB == null || propDB.getCount() < useCount) {
            LogUtils.error("道具材料不足id:" + propId);
            playerController.sendWarn(WordFactory.GOODS_NOT_ENOUGH, propId);
            return;
        }
        if (propDB.getConfig().type != ConstantFactory.PROP_TYPE_LIQUID) {
            LogUtils.error("道具类型错误:" + propId);
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        if (roleType == SGCommonProto.E_GAME_ROLE_TYPE.GAME_ROLE_TYPE_MASTER) {
            SettingInfo info = playerController.getPlayer().getExtInfo(SettingInfo.class);
            if (info.isUseLiquidTouchMax(propId, useCount)) {
//                LogUtils.error("药水使用达到最大值");
                playerController.sendWarn(WordFactory.USE_LIQUID_TOUCH_MAX);
                return;
            }
            info.addLiquidUseCount(propId, useCount);
            //扣除资源
            bagInfo.addProp(propId, -useCount);
            playerController.updateFC();
            S2C_MajorUseLiquid.Builder response = S2C_MajorUseLiquid.newBuilder();
            response.setPropId(propId);
            response.setRoleType(roleType);
            response.setUseCount(useCount);
            response.setTotalUseCount(info.getUseLiquidCount(propId));
            response.setCardId(cardId);


            LogUtils.debug("返回吃药消息：" + response.toString());
            playerController.sendMsg(code, response.build().toByteArray());
            return;


        } else if (roleType == SGCommonProto.E_GAME_ROLE_TYPE.GAME_ROLE_TYPE_SOLDIER) {
            CardDB cardDB = bagInfo.getCardData().getCard(cardId);
            if (cardDB == null) {
                //卡牌不存在
                LogUtils.debug("卡片不存在：" + cardId);
                playerController.sendWarn(WordFactory.CARD_NOTHING_ERROR);
                return;
            }

            if (cardDB.isUseLiquidTouchMax(propId, useCount)) {
//                LogUtils.error("药水使用达到最大值");
                playerController.sendWarn(WordFactory.USE_LIQUID_TOUCH_MAX);
                return;
            }
            cardDB.addLiquidUseCount(propId, useCount);
            //扣除资源
            bagInfo.addProp(propId, -useCount);
            playerController.updateFC();
            S2C_MajorUseLiquid.Builder response = S2C_MajorUseLiquid.newBuilder();
            response.setPropId(propId);
            response.setRoleType(roleType);
            response.setUseCount(useCount);
            response.setTotalUseCount(cardDB.getUseLiquidCount(propId));
            response.setCardId(cardId);

            LogUtils.debug("返回吃药消息：" + response.toString());
            playerController.sendMsg(code, response.build().toByteArray());

        } else {
            LogUtils.error("暂无此角色类型的专业");
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
    }


    /**
     * 合成初始化
     *
     * @param playerController
     * @param code
     * @param data
     */
    private void mergeInit(PlayerController playerController, int code, byte[] data) {
        C2S_MajorMergeInit request = null;
        try {
            request = C2S_MajorMergeInit.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        if (request == null) {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        SGCommonProto.E_MAJOR_TYPE majorType = request.getMajorType();
        if (majorType == SGCommonProto.E_MAJOR_TYPE.MAJOR_TYPE_REFINING) {
            LogUtils.info("合成初始化数据->majorType:", majorType, ",level:", playerController.getPlayer().getMajorInfo().getRefiningData().getLevel());
            playerController.sendMsg(code, S2C_MajorMergeInit.newBuilder().setMajorType(majorType).setLevel(playerController.
                    getPlayer().getMajorInfo().getRefiningData().getLevel()).build().toByteArray());
        } else {
            LogUtils.error("暂无此类型的专业");
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
    }


    /**
     * 合成
     *
     * @param playerController
     * @param code
     * @param data
     */
    private void merge(PlayerController playerController, int code, byte[] data) {
        C2S_MajorMerge request = null;
        try {
            request = C2S_MajorMerge.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        if (request == null) {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        SGCommonProto.E_MAJOR_TYPE majorType = request.getMajorType();
        List<SGCommonProto.GoodsObject> srcMaterial = request.getSrcMaterialList();
        LogUtils.info("材料合成参数:" + request.toString());
        if (majorType == SGCommonProto.E_MAJOR_TYPE.MAJOR_TYPE_REFINING) {
            if (srcMaterial == null || srcMaterial.size() != 3) {
                LogUtils.error("炼制原材料数量有误");
                playerController.sendWarn(WordFactory.REFINING_COUNT_ERROR);
                return;
            }
            List<Integer> list = new ArrayList<>();
            for (SGCommonProto.GoodsObject object : srcMaterial) {
                list.add(object.getId());
            }
            RefiningData myRefiningData = playerController.getPlayer().getMajorInfo().getRefiningData();
            BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
            LogUtils.info("资源数量->", bagInfo.getAssetData());
            List<MajorMergeConfig> mergeConfigs = DataFactory.getInstance().getDataList(DataFactory.MAJOR_MERGE_KEY);
            int size = mergeConfigs.size();
            MajorMergeConfig config;
            for (int i = size - 1; i >= 0; i--) {
                config = mergeConfigs.get(i);
                LogUtils.info("检测炼制参数->config.majorType:", config.majorType, ", config.needSkillLv:", config.needSkillLv, ", myRefiningData.getLevel():", myRefiningData.getLevel());
                LogUtils.info("config.srcMaterial:", config.srcMaterial, ", list:", list);
                if (config.majorType == majorType.getNumber() &&
                        myRefiningData.getLevel() >= config.needSkillLv &&
                        config.srcMaterial.containsAll(list)) {
                    //参数有效，验证自己存量
                    GoodsData[] reduceGoods = new GoodsData[list.size()];
                    for (int j = 0; j < list.size(); j++) {
                        if (bagInfo.getPropCount(list.get(j)) <= 0) {
                            LogUtils.error("道具材料不足id:" + list.get(j));
                            playerController.sendWarn(WordFactory.GOODS_NOT_ENOUGH, list.get(j));
                            return;
                        }
                        reduceGoods[j] = new GoodsData(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_PROPS_VALUE, list.get(j), 1);
                    }
                    //生成目标材料
                    GoodsData goodsData = CoreUtils.getRandomObject(config.desMaterial, config.desMaterialWeight, new ICalculateRandomField<GoodsData>() {
                        @Override
                        public int getFieldValue(GoodsData data) {
                            return data.value;
                        }
                    });
                    goodsData = new GoodsData(goodsData.type, goodsData.id, 1);
                    //增加和扣除道具
                    bagInfo.addGoods(new GoodsData[]{goodsData}, reduceGoods);
                    bagInfo.addGoods(myRefiningData.getExpAsset(), true);

                    // 重新计算炼制等级
                    myRefiningData.calculateLevel();
                    //数据返回
                    SGCommonProto.GoodsObject goodsObject = SGCommonProto.GoodsObject.newBuilder().
                            setType(goodsData.type).
                            setId(goodsData.id).
                            setValue(goodsData.value).build();
                    S2C_MajorMerge.Builder response = S2C_MajorMerge.newBuilder().setMajorType(majorType).
                            setLevel(myRefiningData.getLevel()).setDesMaterial(goodsObject);
                    LogUtils.debug("返回炼制数据:" + response.toString());
                    //检测开服活动是否完成
                    playerController.getPlayer().getSevenDayData().checkAllRewardState(SevenDayFactory.EVENT_TYPE_13,1);

                    playerController.sendMsg(code, response.build().toByteArray());
                    return;
                }
            }

            LogUtils.debug("炼制数据不满足条件");
            playerController.sendWarn(WordFactory.REFINING_UN_MATCH_MENU);
            return;


        } else {
            LogUtils.error("暂无此类型的专业");
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }


    }


    /**
     * 专业的战斗
     *
     * @param playerController
     * @param code
     * @param data
     */
    private void majorBattle(PlayerController playerController, int code, byte[] data) {
        SGChallengeProto.C2S_MajorBattle request = null;
        try {
            request = SGChallengeProto.C2S_MajorBattle.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        if (request == null) {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        SGCommonProto.E_MAJOR_TYPE majorType = request.getMajorType();
        SGCommonProto.E_MAJOR_BATTLE_TYPE battleType = request.getBattleType();
        String objectIndex = request.getObjectIndex();
        String param = request.getParam();
        MajorBattleParam battleParamBean = new MajorBattleParam(objectIndex, majorType.getNumber(), battleType.getNumber(), param);
        if (battleParamBean.checkError()) {
            LogUtils.error("玩家流水号为空");
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        if (majorType == SGCommonProto.E_MAJOR_TYPE.MAJOR_TYPE_COLLECT) {
            CollectData myCollectData = playerController.getPlayer().getMajorInfo().getCollectData();
            if (battleType == SGCommonProto.E_MAJOR_BATTLE_TYPE.MAJOR_BATTLE_TYPE_GRAB) {
                if (myCollectData.getRemainGrabTimes() == 0) {
                    LogUtils.error("剩余抢夺次数不够");
                    playerController.sendWarn(WordFactory.REMAIN_GRAB_TIMES_NOT_ENOUGH);
                    return;
                }
                WorldCollectBean bean = WorldInfoFactory.getInstance().getWorldCollectData().
                        getCollectPlayerByObjectIndex(battleParamBean.getObjectIndex());
                if (bean == null) {
                    LogUtils.error("玩家已经领取采集奖励");
                    playerController.sendWarn(WordFactory.PLAYER_HAS_RECEIVER_COLLECT_REWARD);
                    return;
                }
                if (!bean.isBeGrabTimesEnough()) {
                    LogUtils.error("该玩家本次采集被抢夺次数不够");
                    playerController.sendWarn(WordFactory.BE_GRAB_TIMES_NOT_ENOUGH);
                    return;
                }

                List<GoodsData> list = bean.getGrabGoods();
                myCollectData.addNewBattleToCache(list);
                if (CoreUtils.isFunctionTestAccount(playerController.getPlayer().getAccount())) {
                    majorBattleEnd(playerController, battleParamBean.getBattleStringParam(), true);
                } else {
                    StableDataConfig stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.MAJOR_MAP.getCode());
                    MsgUtils.startBattle(playerController, SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_MAJOR, E_BattleDetailType.PVP_AI_MAJOR, battleParamBean.getBattleStringParam(),
                            new BattleInitParam(stableDataConfig.intValue),
                            new RequestParam(RequestParam.PARAM_MAJOR_TYPE, battleParamBean.getMajorType()),
                            new RequestParam(RequestParam.PARAM_MAJOR_BATTLE_TYPE, battleParamBean.getBattleType()));
                }
            } else if (battleType == SGCommonProto.E_MAJOR_BATTLE_TYPE.MAJOR_BATTLE_TYPE_REVENGE) {
                if (StringUtils.isNullOrEmpty(param)) {
                    LogUtils.error("复仇时间未传递");
                    playerController.sendWarn(WordFactory.PARAM_ERROR);
                    return;
                }

                if (!myCollectData.isRecordExist(battleParamBean.getObjectIndex() + ConstantFactory.UNDERLINE + battleParamBean.getParam())) {
                    LogUtils.error("复仇记录不存在");
                    playerController.sendWarn(WordFactory.COLLECT_REVENGE_RECORD_UN_EXIST);
                    return;
                }
                //battleParamBean.setBattleResult(myCollectData.getRevengeGoods(battleParamBean.getObjectIndex() + ConstantFactory.UNDERLINE + battleParamBean.getParam()));
                if (CoreUtils.isFunctionTestAccount(playerController.getPlayer().getAccount())) {
                    majorBattleEnd(playerController, battleParamBean.getBattleStringParam(), true);
                } else {
                    StableDataConfig stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.MAJOR_MAP.getCode());
                    MsgUtils.startBattle(playerController, SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_MAJOR, E_BattleDetailType.PVP_AI_MAJOR, battleParamBean.getBattleStringParam(),
                            new BattleInitParam(stableDataConfig.intValue),
                            new RequestParam(RequestParam.PARAM_MAJOR_TYPE, battleParamBean.getMajorType()),
                            new RequestParam(RequestParam.PARAM_MAJOR_BATTLE_TYPE, battleParamBean.getBattleType()));
                }
            } else {
                LogUtils.error("战斗类型错误");
                playerController.sendWarn(WordFactory.PARAM_ERROR);
            }
        } else {
            LogUtils.error("暂无此类型的专业");
            playerController.sendWarn(WordFactory.PARAM_ERROR);
        }
//
//        playerController.sendMsg(code, S2C_MajorBattle.newBuilder().setType(majorType).setBattleType(battleType).
//                setBattleId(DataFactory.currentTime + "").build().toByteArray());
    }


    /**
     * 战斗返回
     *
     * @param playerController
     * @param param
     * @param win
     * @return
     */
    public GoodsData[] majorBattleEnd(PlayerController playerController, String param, boolean win) {
        MajorBattleParam battleParamBean = new MajorBattleParam(param);
        LogUtils.debug("战斗参数解析:" + param);
        if (battleParamBean.checkError()) {
            LogUtils.error("战斗参数解析错误:" + param);
            playerController.sendWarn(WordFactory.SERVER_DATA_ERROR);
            return null;
        }

        GoodsData[] grabGoods = null;

        BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
        CollectData myCollectData = playerController.getPlayer().getMajorInfo().getCollectData();
        if (battleParamBean.getMajorType() == SGCommonProto.E_MAJOR_TYPE.MAJOR_TYPE_COLLECT_VALUE) {
            if (battleParamBean.getBattleType() == SGCommonProto.E_MAJOR_BATTLE_TYPE.MAJOR_BATTLE_TYPE_GRAB_VALUE) {
                //获取对方的物品
                myCollectData.addGrabTimes();
                if (win) {
                    // 增加抢夺的材料
                    List<GoodsData> list = myCollectData.getCacheBattleGoods();
                    if (list != null && !list.isEmpty()) {
                        grabGoods = new GoodsData[list.size()];
                        for (int i = 0; i < list.size(); i++) {
                            GoodsData data = list.get(i);
                            grabGoods[i] = new GoodsData(data.type, data.id, data.value);
                        }
                        bagInfo.addGoods(grabGoods);
                    }

                    // 若对方还未领取采集奖励，则增加对方的被抢夺次数
                    WorldCollectBean bean = WorldInfoFactory.getInstance().getWorldCollectData().
                            getCollectPlayerByObjectIndex(battleParamBean.getObjectIndex());
                    if (bean != null) {
                        if (bean.addBeGrabTimes()) {
                            // 被抢夺次数增加成功才会增加抢夺记录，因为这里只记录被抢夺记录次数的玩家
                            TwoTuple<Player, PlayerController> playerResult = GameServer.getInstance().getWorldManager().getPlayerResult(battleParamBean.getObjectIndex());
                            if (playerResult.getFirst() != null && playerResult.getFirst().getUid() != 0) {
                                CollectData collectData = playerResult.getFirst().getMajorInfo().getCollectData();
                                collectData.addBeGrabRecord(playerController.getObjectIndex(), list);
                                if (playerResult.getSecond() == null) {
                                    //离线,要保存玩家数据
                                    GameServer.getInstance().savePlayer(playerResult.getFirst());
                                }
                            }
                        }
                    }
                }
            } else if (battleParamBean.getBattleType() == SGCommonProto.E_MAJOR_BATTLE_TYPE.MAJOR_BATTLE_TYPE_REVENGE_VALUE) {
                if (win) {
                    GoodsData[] goodsDatas = myCollectData.removeRecord(battleParamBean.getObjectIndex() + ConstantFactory.UNDERLINE + battleParamBean.getParam());
                    if (goodsDatas == null) {
                        LogUtils.error("获取复仇物品为空，参数：" + param);
                        playerController.sendWarn(WordFactory.SERVER_DATA_ERROR);
                        return null;
                    }
                    bagInfo.addGoods(goodsDatas, null);
                    grabGoods = goodsDatas;
                    //myCollectData.addNewBattleToCache(Arrays.asList(goodsDatas));
                }
            }
        } else {
            LogUtils.error("暂无此类型的专业");
            playerController.sendWarn(WordFactory.SERVER_DATA_ERROR);
        }
        return grabGoods;
    }


    /**
     * 采集的初始化
     *
     * @param playerController
     * @param code
     * @param data
     */
    private void collectInit(PlayerController playerController, int code, byte[] data) {
        C2S_MajorCollectInit request = null;
        try {
            request = C2S_MajorCollectInit.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        if (request == null) {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        SGCommonProto.E_MAJOR_TYPE majorType = request.getType();
        if (majorType == SGCommonProto.E_MAJOR_TYPE.MAJOR_TYPE_COLLECT) {
            CollectData collectData = playerController.getPlayer().getMajorInfo().getCollectData();
            S2C_MajorCollectInit.Builder response = S2C_MajorCollectInit.newBuilder();
            response.setType(majorType);
            response.setLevel(collectData.getLevel());
            response.setRemainCollectTimes(collectData.getRemainCollectTimes());
            response.setMaxCollectTimes(collectData.getMaxCollectTimes());
            response.setRemainGrabTimes(collectData.getRemainGrabTimes());
            response.setMaxGrabTimes(collectData.getMaxGrabTimes());
            response.addAllFlushPlayers(getMajorPlayerProto(WorldInfoFactory.getInstance().getWorldCollectData().getRandomPlayers(8, playerController.getObjectIndex())));

            WorldCollectData worldCollectData = WorldInfoFactory.getInstance().getWorldCollectData();
            WorldCollectBean myCollectBean = worldCollectData.getCollectPlayerByObjectIndex(playerController.getObjectIndex());

            if (myCollectBean == null) {
                response.setStatus(SGCommonProto.E_MAJOR_COLLECT_STATUS.MAJOR_COLLECT_STATUS_UNCOLLECT);
            } else if (myCollectBean.isTimeIn()) {
                response.setStatus(SGCommonProto.E_MAJOR_COLLECT_STATUS.MAJOR_COLLECT_STATUS_COLLECTING);
                response.setRemainTime(myCollectBean.getEndTime() - DataFactory.currentTime);
            } else {
                response.setStatus(SGCommonProto.E_MAJOR_COLLECT_STATUS.MAJOR_COLLECT_STATUS_COLLECTED);
            }

//            LogUtils.debug("采集初始化：" + response.toString());
            playerController.sendMsg(code, response.build().toByteArray());
        } else {
            LogUtils.error("暂无此类型的专业");
            playerController.sendWarn(WordFactory.PARAM_ERROR);
        }
    }

    /**
     * 采集复仇列表
     *
     * @param playerController
     * @param code
     * @param data
     */
    private void collectRevengeList(PlayerController playerController, int code, byte[] data) {
        C2S_MajorCollectRevengeList request = null;
        try {
            request = C2S_MajorCollectRevengeList.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        if (request == null) {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        SGCommonProto.E_MAJOR_TYPE majorType = request.getType();
        if (majorType == SGCommonProto.E_MAJOR_TYPE.MAJOR_TYPE_COLLECT) {
            CollectData collectData = playerController.getPlayer().getMajorInfo().getCollectData();
            S2C_MajorCollectRevengeList.Builder response = S2C_MajorCollectRevengeList.newBuilder();
            response.addAllRevengePlayers(getMajorPlayerProto(collectData.getRevengePlayer()));
            LogUtils.debug("复仇列表：" + response.toString());
            playerController.sendMsg(code, response.build().toByteArray());
        } else {
            LogUtils.error("暂无此类型的专业");
            playerController.sendWarn(WordFactory.PARAM_ERROR);
        }
    }


    /**
     * 采集开始
     *
     * @param playerController
     * @param code
     * @param data
     */
    private void collectStart(PlayerController playerController, int code, byte[] data) {
        C2S_MajorCollectStart request = null;
        try {
            request = C2S_MajorCollectStart.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        if (request == null) {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        SGCommonProto.E_MAJOR_TYPE majorType = request.getMajorType();
        int collectId = request.getCollectId();
        SGCommonProto.E_MAJOR_COLLECT_TYPE collectType = request.getCollecType();
        if (majorType == SGCommonProto.E_MAJOR_TYPE.MAJOR_TYPE_COLLECT) {
            WorldCollectData worldCollectData = WorldInfoFactory.getInstance().getWorldCollectData();
            WorldCollectBean myCollectBean = worldCollectData.getCollectPlayerByObjectIndex(playerController.getObjectIndex());
            if (myCollectBean != null) {
                LogUtils.error("已存在采集任务");
                playerController.sendWarn(WordFactory.COLLECT_MISSION_EXIST);
                return;
            }
            CollectData collectData = playerController.getPlayer().getMajorInfo().getCollectData();
            if (collectData.getRemainCollectTimes() == 0) {
                LogUtils.error("剩余采集次数不够");
                playerController.sendWarn(WordFactory.REMAIN_COLLECT_TIMES_NOT_ENOUGH);
                return;
            }

            StableDataConfig stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.COLLECT_PRODUCT.getCode());
            GoodsData goodsData = null;
            for (GoodsData configData : stableDataConfig.goods) {
                if (collectId == configData.type) {
                    goodsData = configData;
                    break;
                }
            }
            if (goodsData == null) {
                LogUtils.error("goodsData is null -> collectId:" + collectId);
                playerController.sendWarn(WordFactory.PARAM_ERROR);
                return;
            }

            MajorConfig majorConfig = DataFactory.getInstance().getGameObject(DataFactory.MAJOR_KEY, collectData.getLevel());
            if (majorConfig == null) {
                LogUtils.error("采集信息配置出错,roleID：" + playerController.getObjectIndex() + "，lev：" + collectData.getLevel());
                playerController.sendWarn(WordFactory.REMAIN_COLLECT_TIMES_NOT_ENOUGH);
                return;
            }

            // 是否要扣除道具
            StableDataConfig addPercentConfig = null;
            if (collectType == SGCommonProto.E_MAJOR_COLLECT_TYPE.MAJOR_COLLECT_TYPE_SENIOR) {
                StableDataConfig config = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.COLLECT_SENIOR.getCode());
                if (config == null) {
                    LogUtils.error("StableDataConfig is null -> " + E_StableDataType.COLLECT_SENIOR);
                    playerController.sendWarn(WordFactory.PARAM_ERROR);
                    return;
                }

                addPercentConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.MAJOR_ADD_PERCENT.getCode());
                if (addPercentConfig == null) {
                    LogUtils.error("addPercentConfig is null -> " + E_StableDataType.MAJOR_ADD_PERCENT);
                    playerController.sendWarn(WordFactory.PARAM_ERROR);
                    return;
                }

                BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
                for (GoodsData goods : config.goods) {
                    if (collectId == goods.type) {
                        if (bagInfo.getGoodsCount(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_PROPS_VALUE,
                                goods.id) < goods.value) {
                            //资源不足
                            LogUtils.error("物品不足：" + goods.value);
                            playerController.sendWarn(WordFactory.GOODS_NOT_ENOUGH, goods.id);
                            return;
                        }

                        //扣除资源
                        bagInfo.addGoods(new GoodsData[]{}, new GoodsData[]{new GoodsData(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_PROPS_VALUE,
                                goods.id, goods.value)});
                        break;
                    }
                }
            }

            int endTime = 0;
            if (CoreUtils.isFunctionTestAccount(playerController.getPlayer().getAccount())) {
                endTime = 60000;
            } else {
               endTime = CoreUtils.ONE_MINUTE * goodsData.id;
            }

            int productNum = goodsData.value;
            if (addPercentConfig != null) {
                // 使用黄金镐
                productNum = (int) (productNum * addPercentConfig.intValue * majorConfig.collectExtraRate / 10000f);
            } else {
                // 普通采集
                productNum = (int) (productNum * majorConfig.collectExtraRate / 100f);
            }
            WorldInfoFactory.getInstance().getWorldCollectData().addNewCollectPlayer(new WorldCollectBean(playerController.getObjectIndex(), DataFactory.currentTime + endTime,
                    collectType.getNumber(), collectId, false, productNum, majorConfig));
            collectData.addCollectTimes();
            S2C_MajorCollectStart.Builder response = S2C_MajorCollectStart.newBuilder();
            response.setType(majorType);
            response.setRemainTime(endTime);
            response.setRemainCollectTimes(collectData.getRemainCollectTimes());
            response.setMaxCollectTimes(collectData.getMaxCollectTimes());
            LogUtils.debug("采集开始返回数据: " + response.toString());
            playerController.sendMsg(code, response.build().toByteArray());

            // 检测任务是否完成
            playerController.getPlayer().getExtInfo(TaskInfo.class).check(TaskFactory.TASK_TARAGET_EVERYDAY_MAJOR, 1);
        } else {
            LogUtils.error("暂无此类型的专业");
            playerController.sendWarn(WordFactory.PARAM_ERROR);
        }
    }

    /**
     * 采集结果的领取
     *
     * @param playerController
     * @param code
     * @param data
     */
    private void collectProductionReceiver(PlayerController playerController, int code, byte[] data) {
        C2S_MajorCollectProductionReceiver request = null;
        try {
            request = C2S_MajorCollectProductionReceiver.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        if (request == null) {
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        SGCommonProto.E_MAJOR_TYPE majorType = request.getMajorType();
        if (majorType == SGCommonProto.E_MAJOR_TYPE.MAJOR_TYPE_COLLECT) {
            WorldCollectData worldCollectData = WorldInfoFactory.getInstance().getWorldCollectData();
            WorldCollectBean myCollectBean = worldCollectData.getCollectPlayerByObjectIndex(playerController.getObjectIndex());
            if (myCollectBean == null) {
                LogUtils.error("不存在采集任务");
                playerController.sendWarn(WordFactory.COLLECT_MISSION_UN_EXIST);
                return;
            }

            if (myCollectBean.isTimeIn()) {
                LogUtils.error("正在采集中");
                playerController.sendWarn(WordFactory.COLLECT_MISSION_COLLECTING);
                return;
            }

            //采集奖励
            BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
            bagInfo.addGoods(myCollectBean.getAfterGrabGoods(), null);

            // 增加经验
            int percent = 100;
            if (myCollectBean.getCollectType() == SGCommonProto.E_MAJOR_COLLECT_TYPE.MAJOR_COLLECT_TYPE_SENIOR.getNumber()) {
                StableDataConfig addPercentConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.MAJOR_ADD_PERCENT.getCode());
                percent = addPercentConfig.intValue;
            }
            StableDataConfig config = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.COLLECT_PRODUCT_EXP.getCode());
            for (GoodsData configData : config.goods) {
                if (myCollectBean.getCollectId() == configData.type) {
                    bagInfo.addGoods(new GoodsData(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_ASSETS_VALUE, configData.id, (int) (configData.value * percent / 100f)), true);
                    break;
                }
            }

            playerController.getPlayer().getMajorInfo().getCollectData().calculateLevel();
            playerController.sendMsg(code, S2C_MajorCollectProductionReceiver.newBuilder().
                    setType(majorType).build().toByteArray());
            worldCollectData.removeByObjectIndex(playerController.getObjectIndex());
        } else {
            LogUtils.error("暂无此类型的专业");
            playerController.sendWarn(WordFactory.PARAM_ERROR);
        }
    }

    /**
     * 封装采集玩家信息
     *
     * @param data
     * @return
     */
    public List<SGCommonProto.CollectPlayerInfo> getMajorPlayerProto(List<WorldCollectBean> data) {
        List<SGCommonProto.CollectPlayerInfo> list = new ArrayList<>();
        if (data == null || data.size() == 0) {
            return list;
        }

        List<String> playerIds = new ArrayList<>();
        for (WorldCollectBean bean : data) {
            String[] param = bean.getObjectIndex().split(ConstantFactory.UNDERLINE);
            playerIds.add(param[0]);
            bean.setObjectIndex(param[0]);
            if (param.length == 2) {
                bean.param = param[1];
            }
        }
        if (playerIds.size() == 0) {
            return list;
        }

        List<PlayerModel> playerListByIndex = playerService.getPlayerListByIndex(playerIds);

        for (WorldCollectBean bean : data) {
            List<GoodsData> goodsDataList = bean.getGoodsDatas();
            SGCommonProto.CollectPlayerInfo.Builder playerInfo = SGCommonProto.CollectPlayerInfo.newBuilder();
            playerInfo.setObjectIndex(bean.getObjectIndex());
            playerInfo.setInitValue1(bean.getBeGrabTimes());
            playerInfo.setInitValue2(bean.MAX_GRAP_TIMES);
            for (GoodsData goodsData : goodsDataList) {
                playerInfo.addGoods(SGCommonProto.GoodsObject.newBuilder().setType(goodsData.type).
                        setId(goodsData.id).setValue(goodsData.value));
            }
            PlayerModel model = getPlayerInList(playerListByIndex, bean.getObjectIndex());
            if (model != null) {
                playerInfo.setName(model.getName());
                playerInfo.setFightingCapacity(model.getFc());
                playerInfo.setMasterId(model.getMaster());
                playerInfo.setCampValue(model.getCamp());
                playerInfo.setAvatar(model.getAvatar());
                playerInfo.setStringValue(bean.param == null ? "" : bean.param);
            } else {
                LogUtils.debug("根据玩家的索引无法查到玩家， 索引为: " + bean.getObjectIndex());
                continue;
            }

            list.add(playerInfo.build());
        }
        return list;
    }


    /**
     * 获取用户
     *
     * @param playerListByIndex
     * @param objectIndex
     * @return
     */
    private PlayerModel getPlayerInList(List<PlayerModel> playerListByIndex, String objectIndex) {
        for (PlayerModel model : playerListByIndex) {
            if (model.getObjectIndex().equals(objectIndex)) {
                return model;
            }
        }
        return null;
    }


}
